package com.aliyun.gts.sso.util;

import com.aliyun.gts.sso.boot.SFSSOLoginProperties;
import com.aliyun.gts.sso.constant.SFSSOLoginConstants;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * Created by 鸿度 on 2024-06-18 11:36.
 */
@Slf4j
public class SFSSOLoginUtils {


    private static volatile String sso302HtmlTemplate;

    public static String build302RedirectHtml(String redirectURL) {
        if (sso302HtmlTemplate == null) {
            InputStream inputStream = SFSSOLoginUtils.class.getClassLoader().getResourceAsStream("templates/sf_sso_302.html");
            try {
                sso302HtmlTemplate = IOUtils.toString(inputStream);
            } catch (IOException e) {
                log.error("cannot find sso302HtmlTemplate", e);
            }
        }
        return sso302HtmlTemplate.replace("[(${sso_redirect_url})]", redirectURL);
    }


    public static void sendHtmlText(HttpServletResponse response, String htmlText) throws IOException {
        response.setContentType(SFSSOLoginConstants.TEXT_HTML_UTF8_VALUE);
        response.getWriter().write(htmlText);
    }

    public static String getRequestURI(HttpServletRequest request) {
        String requestUri = StringUtils.trimToEmpty(request.getRequestURI());
        if (StringUtils.containsIgnoreCase(requestUri, "%2e") || requestUri.contains("..")) {
            requestUri = StringUtils.trimToEmpty(request.getServletPath());
        }
        return requestUri;
    }


    public static String encodeURL(String s) {
        try {
            return URLEncoder.encode(s, SFSSOLoginConstants.DEFAULT_ENCODING);
        } catch (UnsupportedEncodingException e) {
            log.error("Cannot encode URL", e);
        }
        return s;
    }


    public static String builderLoginRedirectURL(SFSSOLoginProperties sfSSOLoginProperties, HttpServletRequest request) throws IOException {
        // 构造跳转地址
        StringBuilder sb = new StringBuilder();
        String reqURL = SFSSOLoginUtils.parseRequestURL(sfSSOLoginProperties, request);
        sb.append(sfSSOLoginProperties.getUrl());
        sb.append("/sso/login?service=");
        String encodeUrl = SFSSOLoginUtils.encodeURL(String.format("%s/loginCallback?callbackUrl=%s",
                buildDomainURL(sfSSOLoginProperties),
                reqURL));
        sb.append(encodeUrl);
        return sb.toString();
    }

    public static String builderLogoutRedirectURL(SFSSOLoginProperties sfSSOLoginProperties) {
        // 构造跳转地址
        StringBuilder sb = new StringBuilder();
        sb.append(sfSSOLoginProperties.getUrl());
        sb.append("/logout?service=");
        String encodeUrl = SFSSOLoginUtils.encodeURL(buildDomainURL(sfSSOLoginProperties));
        sb.append(encodeUrl);
        return sb.toString();
    }

    private static String buildDomainURL(SFSSOLoginProperties props) {
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(props.getSchema());
        urlBuilder.append("://");
        urlBuilder.append(props.getHost());
        if (SFSSOLoginConstants.SCHEMA_HTTPS.equalsIgnoreCase(props.getSchema()) && !new Integer(443).equals(props.getPort())) {
            urlBuilder.append(":");
            urlBuilder.append(props.getPort());
        }
        if (SFSSOLoginConstants.SCHEMA_HTTP.equalsIgnoreCase(props.getSchema()) && !new Integer(80).equals(props.getPort())) {
            urlBuilder.append(":");
            urlBuilder.append(props.getPort());
        }
        return urlBuilder.toString();
    }

    public static String parseRequestURL(SFSSOLoginProperties sfSSOLoginProperties, HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        sb.append(buildDomainURL(sfSSOLoginProperties));
        sb.append(request.getContextPath());
        sb.append(request.getRequestURI());
        if (StringUtils.isNotBlank(request.getQueryString())) {
            sb.append("?").append(request.getQueryString());
        }
        return sb.toString();
    }
}

